﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using MapLibrary;

namespace MapLibrary
{
    public class Map
    {
        private List<Layer> mLayers;

        private string mMapName;

        private Palette mPalette;

        public Map()
        {
            mLayers = new List<Layer>();

            mPalette = new Palette();
        }

        /// <summary>
        /// Constructs the layers for the Map.  Note that the Map is composed of 10 layers,
        /// the bottom most layer being a tiled layer.
        /// </summary>
        private void ConstructLayers()
        {
            if (mLayers.Count < 10)
            {
                for (int i = 0; i < 10; i++)
                {
                    mLayers.Add(new Layer());
                }
            }
        }

        /// <summary>
        /// The unique name representation of this map.
        /// </summary>
        public string Name
        {
            get { return mMapName; }
            set { mMapName = value; }
        }

        /// <summary>
        /// The Palette for this map.  Gives the list of MapNodes that the map
        /// uses for node placement.
        /// </summary>
        public Palette Palette
        {
            get { return mPalette; }
            set { mPalette = value; }
        }

        /// <summary>
        /// All of the layers in this map.
        /// </summary>
        public List<Layer> Layers
        {
            get { return mLayers; }
            set { mLayers = value; }
        }

        /// <summary>
        /// Draw the map onto the viewport.
        /// </summary>
        /// <param name="batch"></param>
        /// <param name="Viewport"></param>
        public void Draw(SpriteBatch batch, WorldViewport Viewport)
        {
            foreach (Layer layer in mLayers)
            {
                layer.Draw(batch, Viewport);
            }
        }
    }

    public class MapContentReader : ContentTypeReader<Map>
    {
        protected override Map Read(ContentReader input, Map existingInstance)
        {
            Map map;
            if (existingInstance != null)
                map = existingInstance;
            else
                map = new Map();

            map.Name = input.ReadString();
            map.Palette = input.ReadObject<Palette>();
            int numLayers = input.ReadInt32();
            for (int i = 0; i < numLayers; i++)
            {
                map.Layers.Add(input.ReadObject<Layer>());
            }
            
            return map;
        }
    }

    //DONT remove this reference.  It is needed by the SaveManager to write out the map.
    public class MapTypeWriter : ContentTypeWriter<Map>
    {
        protected override void Write(ContentWriter output, Map value)
        {
            output.Write(value.Name);
            output.WriteObject<Palette>(value.Palette);
            output.Write(value.Layers.Count);

            foreach (Layer lay in value.Layers)
            {
                output.WriteObject<Layer>(lay);
            }
        }

        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            // TODO: change this to the name of your ContentTypeReader
            // class which will be used to load this data.
            return typeof(MapContentReader).AssemblyQualifiedName;
        }
    }
}
